package com.chalk.config.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * APP登录Token的生成和解析
 *
 * @date: 2019-04-01 下午 05:01
 * @author: zhaobo0119@outlook.com
 * @Descriptopn:
 */
public class JwtTokenUtils {


    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "bearer ";

    private static final String SECRET = "1chalk@!";
    private static final String ISS = "echisan";

    private static final String START_INDEX = "eyJhbGciOiJIUzI1NiJ9.";


    // 添加角色的key
    private static final String ROLE_CLAIMS = "role";

    /**
     * 创建token
     *
     * @param username 用户名
     * @param role     角色
     * @return
     */
    public static String createToken(String username, String role, long expiration) {
        Map<String, Object> map = new HashMap<>();
        map.put(ROLE_CLAIMS, role);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setClaims(map)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
    }

    /**
     * 创建刷新token
     *
     * @param username 用户名
     * @return
     */
    public static String createRefreshToken(String username) {
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .compact();
    }

    /**
     * 用户 id 加盐
     * @return
     */
    public static String signUserId(String userId){
        String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, SECRET).setSubject(userId).compact();
        return compact.replace(START_INDEX, "");
    }

    /**
     * 用户 id 解盐
     * @param compact
     * @return
     */
    public static String solutionUserId(String compact){
        try {
            String subject = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(START_INDEX+"."+compact).getBody().getSubject();
            return subject;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * 从token中获取用户名
     *
     * @param token
     * @return
     */
    public static String getUsername(String token) {
        return getTokenBody(token).getSubject();
    }

    /**
     * 是否已过期
     *
     * @param token
     * @return
     */
    public static boolean isExpiration(String token) {
        return getTokenBody(token).getExpiration().before(new Date());
    }

    private static Claims getTokenBody(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            return new DefaultClaims();
        }
    }

    /**
     * 从token中获取用户角色
     *
     * @param token
     * @return
     */
    public static String getUserRole(String token) {
        return getTokenBody(token).get(ROLE_CLAIMS, String.class);
    }
}
